const express = require('express');
const http = require('http');
const WebSocket = require('ws');
const cors = require('cors');
const { v4: uuidv4 } = require('uuid');
const bodyParser = require('body-parser');

// 初始化Express应用
const app = express();
app.use(cors());
app.use(bodyParser.json());

// 服务器状态存储
const clients = new Map(); // 在线用户 { id, username, ws, status, lastActive }
const chatHistory = []; // 聊天记录 { id, senderId, username, content, timestamp, target }
const userChatTargets = new Map(); // 用户当前聊天目标

// HTTP API接口
// 1. 获取在线用户列表
app.get('/api/online-users', (req, res) => {
  const onlineUsers = Array.from(clients.values()).map(client => ({
    id: client.id,
    username: client.username,
    status: client.status,
    lastActive: client.lastActive
  }));
  
  res.json({
    success: true,
    data: onlineUsers
  });
});

// 2. 获取聊天记录
app.get('/api/chat-history', (req, res) => {
  const { target = 'all', limit = 100, offset = 0 } = req.query;
  
  // 过滤聊天记录
  let filteredHistory = chatHistory;
  if (target !== 'all') {
    filteredHistory = chatHistory.filter(msg => 
      msg.target === 'all' || 
      msg.target === target || 
      msg.senderId === target
    );
  }
  
  // 分页处理
  const paginatedHistory = filteredHistory
    .slice(offset, offset + parseInt(limit))
    .reverse(); // 最新的消息在后面
    
  res.json({
    success: true,
    data: paginatedHistory,
    pagination: {
      total: filteredHistory.length,
      limit: parseInt(limit),
      offset: parseInt(offset)
    }
  });
});

// 3. 发送消息（HTTP备用接口，主要用WebSocket）
app.post('/api/send-message', (req, res) => {
  const { clientId, content, target = 'all' } = req.body;
  
  if (!clientId || !content || !clients.has(clientId)) {
    return res.status(400).json({
      success: false,
      message: '无效的请求参数'
    });
  }
  
  const client = clients.get(clientId);
  const message = {
    id: uuidv4(),
    senderId: clientId,
    username: client.username,
    content,
    timestamp: Date.now(),
    target
  };
  
  // 保存消息到历史记录
  chatHistory.push(message);
  
  // 通过WebSocket广播消息
  broadcastMessage(message);
  
  res.json({
    success: true,
    data: message
  });
});

// 4. 更改用户名
app.post('/api/change-username', (req, res) => {
  const { clientId, newUsername } = req.body;
  
  if (!clientId || !newUsername || !clients.has(clientId)) {
    return res.status(400).json({
      success: false,
      message: '无效的请求参数'
    });
  }
  
  const client = clients.get(clientId);
  const oldUsername = client.username;
  client.username = newUsername.trim();
  
  // 广播用户名更改
  broadcastSystemMessage(`${oldUsername} 改名为 ${client.username}`);
  broadcastUserListUpdate();
  
  res.json({
    success: true,
    data: {
      clientId,
      username: client.username
    }
  });
});

// WebSocket相关功能
const server = http.createServer(app);
const wss = new WebSocket.Server({ server });

// 生成客户端ID
function generateClientId() {
  return uuidv4();
}

// 广播消息给所有客户端
function broadcastMessage(message) {
  const jsonData = JSON.stringify({
    type: 'message',
    data: message
  });
  
  // 如果是群聊，发给所有人；如果是私聊，只发给目标和发送者
  if (message.target === 'all') {
    clients.forEach(client => {
      if (client.ws.readyState === WebSocket.OPEN) {
        client.ws.send(jsonData);
      }
    });
  } else {
    // 发送给目标用户
    const targetClient = clients.get(message.target);
    if (targetClient && targetClient.ws.readyState === WebSocket.OPEN) {
      targetClient.ws.send(jsonData);
    }
    
    // 发送给发送者自己
    const senderClient = clients.get(message.senderId);
    if (senderClient && senderClient.ws.readyState === WebSocket.OPEN) {
      senderClient.ws.send(jsonData);
    }
  }
}

// 广播系统消息
function broadcastSystemMessage(message) {
  const systemMessage = {
    type: 'system',
    data: {
      message,
      timestamp: Date.now()
    }
  };
  
  clients.forEach(client => {
    if (client.ws.readyState === WebSocket.OPEN) {
      client.ws.send(JSON.stringify(systemMessage));
    }
  });
}

// 广播用户列表更新
function broadcastUserListUpdate() {
  const userList = Array.from(clients.values()).map(client => ({
    id: client.id,
    username: client.username,
    status: client.status,
    lastActive: client.lastActive
  }));
  
  const userListMessage = {
    type: 'userList',
    data: userList
  };
  
  clients.forEach(client => {
    if (client.ws.readyState === WebSocket.OPEN) {
      client.ws.send(JSON.stringify(userListMessage));
    }
  });
}

// 处理WebSocket连接
wss.on('connection', (ws) => {
  const clientId = generateClientId();
  console.log(`新客户端连接: ${clientId}`);
  
  // 初始化客户端信息
  const clientInfo = {
    id: clientId,
    username: `用户${Math.floor(Math.random() * 1000)}`,
    ws,
    status: 'online',
    lastActive: Date.now()
  };
  
  clients.set(clientId, clientInfo);
  userChatTargets.set(clientId, 'all');
  
  // 向新连接的客户端发送初始化信息
  ws.send(JSON.stringify({
    type: 'init',
    data: {
      clientId,
      username: clientInfo.username,
      onlineUsers: Array.from(clients.values()).map(c => ({
        id: c.id,
        username: c.username,
        status: c.status
      }))
    }
  }));
  
  // 广播新用户加入
  broadcastSystemMessage(`${clientInfo.username} 加入了聊天`);
  broadcastUserListUpdate();
  
  // 处理客户端消息
  ws.on('message', (message) => {
    try {
      const data = JSON.parse(message);
      clientInfo.lastActive = Date.now();
      clientInfo.status = 'online';
      
      switch (data.type) {
        case 'message':
          // 处理发送消息
          const newMessage = {
            id: uuidv4(),
            senderId: clientId,
            username: clientInfo.username,
            content: data.content,
            timestamp: Date.now(),
            target: userChatTargets.get(clientId)
          };
          
          chatHistory.push(newMessage);
          broadcastMessage(newMessage);
          break;
          
        case 'changeUsername':
          // 处理更改用户名
          const oldUsername = clientInfo.username;
          clientInfo.username = data.newUsername.trim() || oldUsername;
          
          broadcastSystemMessage(`${oldUsername} 改名为 ${clientInfo.username}`);
          broadcastUserListUpdate();
          
          ws.send(JSON.stringify({
            type: 'usernameChanged',
            data: {
              clientId,
              username: clientInfo.username
            }
          }));
          break;
          
        case 'changeChatTarget':
          // 处理更改聊天目标
          if (data.targetId === 'all' || clients.has(data.targetId)) {
            userChatTargets.set(clientId, data.targetId);
            
            const targetName = data.targetId === 'all' 
              ? '全体成员' 
              : clients.get(data.targetId)?.username || '未知用户';
              
            ws.send(JSON.stringify({
              type: 'chatTargetChanged',
              data: {
                targetId: data.targetId,
                targetName
              }
            }));
          }
          break;
          
        case 'setStatus':
          // 处理更改在线状态
          if (['online', 'away', 'busy'].includes(data.status)) {
            clientInfo.status = data.status;
            broadcastUserListUpdate();
          }
          break;
      }
    } catch (error) {
      console.error('消息处理错误:', error);
    }
  });
  
  // 处理连接关闭
  ws.on('close', () => {
    console.log(`客户端断开连接: ${clientId}`);
    const username = clientInfo.username;
    
    clients.delete(clientId);
    userChatTargets.delete(clientId);
    
    broadcastSystemMessage(`${username} 离开了聊天`);
    broadcastUserListUpdate();
  });
  
  // 处理错误
  ws.on('error', (error) => {
    console.error('WebSocket错误:', error);
  });
});

// 启动服务器
const PORT = process.env.PORT || 3001;
server.listen(PORT, () => {
  console.log(`服务器运行在 http://localhost:${PORT}`);
  console.log(`WebSocket运行在 ws://localhost:${PORT}`);
});
    